#coding:utf-8
"""
        主程序入口
"""


import datetime
import wx
import wx.aui as aui
import wx.lib.scrolledpanel as scrolled
import wx.lib.platebtn as platebtn
import wx.grid as gridlib
import wx.lib.buttonpanel as bp
import wx.lib.customtreectrl as customtreectrl
import pickle
import os, sys
import time
import customwid as wid
import stock
import testcase
import database as db
import server
from dttime import now
import ico
import report
import reportform

'''
from wx.lib.activexwrapper import MakeActiveXClass
import win32com.client.gencache as win32
mapxControl = win32.EnsureModule('{9D6ED199-5910-11D2-98A6-00A0C9742CCA}',0,4,0)
if mapxControl is None:
    raise ImportError("Can't load mapx4.5. Make sure you have mapx4.5 installed.")

class MapEvent:
    def OnMouseDown(self, btn, shift, x, y):
        if btn ==2:
            self.CurrentTool = 1001
        
class MapPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        wx.Panel.__init__(self, *args, **kwds)
        ActiveXWrapper = MakeActiveXClass(mapxControl.Map, eventClass = MapEvent)
        self.mapx = ActiveXWrapper(self)
        sizer = wx.BoxSizer()
        sizer.Add(self.mapx, flag=wx.EXPAND, proportion = 1)
        #self.mapx.Geoset = 'D:\厦门地图\信息港（新）.gst'
        self.mapx.MousewheelSupport = 3
        self.mapx.Title.Visible = False
        self.mapx.Refresh()
        self.SetSizer(sizer)
        self.Fit()
'''
class _VehicleStateBar(wx.PyPanel):
    def __init__(self, parent, tel = ""):
        wx.PyPanel.__init__(self, parent)
        self.vehicle = wx.StaticText(self, label = tel)
        self.vehicle.SetForegroundColour(wx.RED)
        self.progress = wid.ProgressBar(self, style =wx.BORDER_SIMPLE)
        self.progress.SetSizeHints(400, 18, 400, 18)
        btnRefresh = _BitmapButton(self, ico.getBmp(u"refresh"), 
                                   self.OnRefresh, (18, 18))
        btnRefresh.SetToolTipString(u"刷新")
        btnDelete = _BitmapButton(self, ico.getBmp(u"delete"), 
                                   self.OnDelete, (18, 18))
        btnDelete.SetToolTipString(u"删除")
        sizer = wid.Sizer(wx.HORIZONTAL, flag = wx.RIGHT, border = 5)
        sizer.Attach(self.progress, btnRefresh, btnDelete)
        mainsizer = wid.Sizer(wx.VERTICAL, flag = wx.ALL, border = 3)
        mainsizer.Attach(self.vehicle, sizer)
        self.SetSizer(mainsizer)
        
        self.Start = self.progress.Start
        self.Stop = self.progress.Stop
        
    def OnRefresh(self, evt):
        self.GetParent().GetParent().requestTestProcess(self.GetLabel())
        
    def OnDelete(self, evt):
        self.GetParent().GetParent().requestStopTest(self.GetLabel())
    
    def GetValue(self):
        return self.progress.GetValue()
    
    def SetValue(self, value, max):
        self.progress.SetRange(max)
        self.progress.SetValue(value)
        
    def GetLabel(self):
        label = self.vehicle.GetLabel()
        return str(label)

class TestStatePanel(aui.AuiNotebook):
    def __init__(self, parent):
        aui.AuiNotebook.__init__(self, parent, style = aui.AUI_NB_BOTTOM|
                                    aui.AUI_NB_TAB_SPLIT|wx.BORDER_NONE)
        self.SetTabCtrlHeight(22)
        self.SetSelectedFont(wid.Font(8))
        items = (
                 (u"信息", True, ico.getBmp(u'info'), self._initMessagePanel),
                 (u"数据", False, ico.getBmp(u'info'), self._initDataPanel),
                 (u"状态", False, ico.getBmp(u'state'), self._initStatePanel),
                 )
        for item in items:
            self.AddPage(*item)

    def AddPage(self, caption, selected, bmp, controlClass, *args, **kw):
        ctrl = controlClass(self, *args, **kw)
        super(TestStatePanel, self).AddPage(ctrl, caption, selected)
        self.SetPageBitmap(self.GetPageCount()-1, bmp)
        return ctrl  

    def _initMessagePanel(self, parent):
        panel = wx.ListCtrl(parent, style = wx.LC_REPORT)
        panel.InsertColumn(0, u'时间', width = 150)
        panel.InsertColumn(1, u'消息', width = 400)
        panel.SetFont(wid.Font(8))
        
        def writeMessage(msg):
            index = panel.InsertStringItem(0, now())
            panel.SetStringItem(index, 1, msg)
            status_panel.setLabel(msg)
        
        mnu_clear = wx.NewId()
        menu = wx.Menu("")
        menu.Append(mnu_clear, "清空")
        
        panel.Bind(wx.EVT_MENU, lambda evt: panel.DeleteAllItems(), id = mnu_clear)
        panel.Bind(wx.EVT_RIGHT_DOWN, lambda evt: panel.PopupMenu(menu))
        

        self.writeMessage = writeMessage
        return panel
    
    def _initStatePanel(self, parent):
        panel = scrolled.ScrolledPanel(parent, style = wx.BORDER_SUNKEN)
        panel.SetBackgroundColour(wx.WHITE)
        mainsizer = wid.Sizer(wx.VERTICAL, flag = wx.EXPAND|wx.ALL, border = 5)
        panel.SetSizer(mainsizer)
        panel.SetupScrolling()
        
        def appendStatePanel(tel):
            for child in panel.GetChildren():
                if tel == child.GetLabel():
                    return
            else:
                mainsizer.Add(_VehicleStateBar(panel, tel))
            panel.SetupScrolling()
            
        def removeStatePanel(tel):
            for child in panel.GetChildren():
                if tel == child.GetLabel():
                    mainsizer.Remove(child)
                    child.Destroy()
            panel.SetupScrolling()
            
        def startTimer(tel):
            for child in panel.GetChildren():
                if tel == child.GetLabel():
                    child.Start()
                    
        def stopTimer(tel):
            for child in panel.GetChildren():
                if tel == child.GetLabel():
                    child.Stop()
            
        def writeState(tel, value, max):
            for child in panel.GetChildren():
                if tel == child.GetLabel():
                    child.SetValue(value, max)

        self.appendVehicleState = appendStatePanel
        self.writeState = writeState
        self.showVehicleTestStarted = startTimer
        self.showVehicleTestPaused = stopTimer
        self.showVehicleTestStoped = removeStatePanel
        return panel
    
    def _initDataPanel(self, parent):
        panel = wx.ListCtrl(parent, style = wx.LC_REPORT)
        panel.InsertColumn(0, u'时间', width = 150)
        panel.InsertColumn(1, u'手机号', width = 100)
        panel.InsertColumn(2, u'数据', width = 900)
        panel.SetFont(wid.Font(8))
        
        def writeData(tel, data):
            index = panel.InsertStringItem(0, now())
            panel.SetStringItem(index, 1, tel)
            panel.SetStringItem(index, 2, data)
            
        mnu_clear = wx.NewId()
        menu = wx.Menu("")
        menu.Append(mnu_clear, "清空数据")
        
        panel.Bind(wx.EVT_MENU, lambda evt: panel.DeleteAllItems(), id = mnu_clear)
        panel.Bind(wx.EVT_RIGHT_DOWN, lambda evt: panel.PopupMenu(menu))
        
        self.writeData = writeData
        return panel
        
    def requestTestProcess(self, tel):
        self.GetParent().requestTestProcess(tel)
        
    def requestStopTest(self, tel):
        dlg = wid.AskingDialog(self, u"确定删除进行中的测试?")
        if dlg.ShowModal() == wx.ID_OK:
            self.GetParent().requestStopTest(tel)
        dlg.Destroy()

class CustomFrameMixin:
    def _initFrameEvent(self):
        self.Bind(wx.EVT_LEFT_DOWN, self._OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self._OnLeftUp)
        self.Bind(wx.EVT_MOTION, self._OnMouseMove)
        self.Bind(wx.EVT_PAINT, self._OnPaint)
    
    def _OnLeftDown(self, evt):
        x, y = self.ClientToScreen(evt.GetPosition())
        originx, originy = self.GetPosition()
        self.space = (x - originx, y - originy)
        self.CaptureMouse()
        
    def _OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()
        self.Move(self.GetPosition())
            
    def _OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown() and self.HasCapture():
            x, y = self.ClientToScreen(evt.GetPosition())
            fp = (x - self.space[0], y - self.space[1])
            self.Move(fp)
            
    def _OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        col1 = wx.Color(30,70,140)
        col2 = wx.Color(200,200,200)
        rect = self.GetClientRect()
        grad = gc.CreateLinearGradientBrush(0, 20, rect.width, 20, col1, col2)
        gc.SetBrush(grad)
        gc.DrawRectangle(0, 0, rect.width - 0, rect.height - 0)
        gc.SetFont(wid.Font(9, bold = True) ,wx.WHITE)
        gc.DrawText(self.caption,10,1)
        evt.Skip()

class ChildFrame(wx.Frame, CustomFrameMixin):
    def __init__(self, parent, caption):
        wx.Frame.__init__(self, parent, style = wx.FRAME_SHAPED|wx.FRAME_FLOAT_ON_PARENT, title = caption)
        self.caption = caption
        
        sizer = wid.Sizer(wx.HORIZONTAL, flag = wx.ALL, border = 1)
        self.buttonboxes = wid.OperationPanel(self, '')
        
        items = [
                (ico.getBmp(u'f_staytop'), wx.ITEM_CHECK, u'置于最前', self.OnStayTop),
                (ico.getBmp(u'f_close'), wx.ITEM_NORMAL, u'关闭', self.OnClose),
                ]
        buttons = self.buttonboxes.layout(items)
        
        sizer.Add((0,0), proportion = 1)
        sizer.Add(self.buttonboxes)
        self.mainsizer = wid.Sizer(wx.VERTICAL, flag = wx.EXPAND)
        self.mainsizer.Add(sizer)
        self.SetSizer(self.mainsizer)
        self.Fit()
        
        self._initFrameEvent()
        
    def AddPanel(self, panel):
        self.panel = panel
        self.mainsizer.Add(panel)
        self.Fit()
        
    def OnStayTop(self, evt):
        style = self.GetWindowStyle()
        if style&wx.STAY_ON_TOP == wx.STAY_ON_TOP:
            self.SetWindowStyle(style&(~wx.STAY_ON_TOP))
        else:
            self.SetWindowStyle(style|wx.STAY_ON_TOP)
         
    def OnMinimize(self, evt):
        print self.buttonboxes.GetControls()
        print self.buttonboxes.GetChildren()
        
    def OnClose(self, evt):
        self.Destroy()    
        

def new_childFrame(parent, caption, _class, *args, **kw):
    child = ChildFrame(parent, caption)
    child.AddPanel(_class(child, *args, **kw))
    return child

class _BitmapButton(wx.PyWindow):
    def __init__(self, parent, bmp, event, size = (14, 14)):
        wx.PyWindow.__init__(self, parent, size = size)
        self.bmp = bmp
        self.evt = event
        self.SetBackgroundColour(wx.WHITE) 
        self.x, self.y = 0, 0
        self.Bind(wx.EVT_PAINT, self._OnPaint)
        self.Bind(wx.EVT_SIZE, lambda evt: self.Refresh())
        self.Bind(wx.EVT_LEFT_DOWN, lambda evt:self.showPressed())
        self.Bind(wx.EVT_LEFT_UP, lambda evt:self.showNormal())
        self.Bind(wx.EVT_LEAVE_WINDOW, lambda evt:self.showNormal())

    def showPressed(self):
        self.x, self.y = 2, 2
        self.Refresh()
        self.evt(None)
        
    def showNormal(self):
        self.x, self.y = 0, 0
        self.Refresh()
         
    def _OnPaint(self, evt):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, self.x, self.y)
        evt.Skip()

class _EditableList(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour(wx.WHITE)
        self.list = wx.ListBox(self, style = wx.BORDER_SIMPLE)
        self._dataList = []   
        items = (
                 (ico.getBmp(u"moveup"), self.OnMoveUp),
                 (ico.getBmp(u"movedown"), self.OnMoveDown),
                 (ico.getBmp(u"remove"), self.OnRemove, ),
                 (ico.getBmp(u"clear"), self.OnClear, ),
                 )
        sizer = wid.Sizer(wx.VERTICAL, flag = wx.ALL, border = 1)
        for item in items:
            btn = _BitmapButton(self, item[0], item[1], (14, 14))
            sizer.Add(btn)

        mainsizer = wid.Sizer(wx.HORIZONTAL)
        mainsizer.Add(self.list, proportion = 1)
        mainsizer.Add(sizer)
        self.SetSizer(mainsizer)
        self.Layout()

    def Append(self, text, data = None):
        self.list.Append(text)
        self._dataList.append(data)
        return len(self._dataList)
        
    def Delete(self, index):
        text = self.list.GetString(index)
        data = self._dataList.pop(index)
        self.list.Delete(index)
        return text, data
        
    def Insert(self, text, index, data = None):
        self.list.Insert(text, index)
        self._dataList.insert(index, data)
        
    def Clear(self):
        self.list.Clear()
        self._dataList = []
        
    def SetData(self, index, data):
        cnt = self.list.GetCount()
        assert index < cnt
        self._dataList[index] = data
        
    def GetCount(self):
        return self.list.GetCount()
    
    def GetString(self, index):
        return self.list.GetString(index)
    
    def GetData(self, index):
        return self._dataList[index]

    def OnMoveUp(self, evt):
        index = self.list.GetSelection()
        if index > 0:
            text, data = self.Delete(index)
            index -= 1
            self.Insert(text, index, data)
            self.list.SetSelection(index)
            
    def OnMoveDown(self, evt):
        index = self.list.GetSelection()
        if index >=0 and index < self.list.GetCount() - 1:
            text, data = self.Delete(index)
            index += 1
            self.Insert(text, index, data)
            self.list.SetSelection(index)
            
    def OnRemove(self, evt):
        index = self.list.GetSelection()
        if index >= 0 :
            self.Delete(index)
            
    def OnClear(self, evt):
        self.Clear()

class TestConfigPanel(scrolled.ScrolledPanel):
    def __init__(self, parent):
        scrolled.ScrolledPanel.__init__(self, parent)
        self.SetBackgroundColour(wx.WHITE)
        labelTel = wx.StaticText(self, label = u"可执行车辆:")
        self.tel = _EditableList(self)
        labelTest = wx.StaticText(self, label = u"测试用例:")
        self.test = _EditableList(self)
        
        sizer = wid.Sizer(wx.VERTICAL, flag = wx.EXPAND | wx.ALL, border = 2)
        sizer.Attach(labelTel, self.tel, labelTest)
        sizer.Add(self.test, proportion = 1)
        
        self.start = wid.CustomBitmapButton(self, ico.getBmp(u"start"))
        
        mainsizer = wid.Sizer(wx.HORIZONTAL, flag = wx.ALL, border = 2)
        mainsizer.Attach(sizer, proportion = 1)
        mainsizer.Attach(self.start)
        self.SetSizer(mainsizer)
        self.SetupScrolling()
        self.Bind(wx.EVT_BUTTON, self.OnStartPlay, self.start)
        
    def addTest(self, name, item):
        self.GetParent().showPanel(self)
        self.test.Append(name, item)
    
    def addVehicle(self, vehicle):
        self.GetParent().showPanel(self)
        for index in xrange(self.tel.GetCount()):
            if vehicle == self.tel.GetString(index):
                return
        else:
            self.tel.Append(vehicle)
        
    def OnStartPlay(self, evt):
        testList = []
        errors = []
        path = ''
        '''dlg = wid.SaveDialog(self, wildcard = "测试报告(*.report)|*.report|(*.*)|*.*")
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
        dlg.Destroy()
        if not path:return
        '''
        for index in xrange(self.test.GetCount()):
            filename = self.test.GetData(index)
            try:
                test = stock.load(filename)
                testList.append(test)
            except Exception:
                errors.append(filename)
        if errors:
            s = ("\n%s"*len(errors))%tuple(errors)
            dlg = wid.AskingDialog(self, u"以下脚本不能正常打开,是否忽略这些脚本继续测试?%s"%s)
            if dlg.ShowModal() == wx.ID_CANCEL:
                return
            
        for index in xrange(self.tel.GetCount()):
            tel = self.tel.GetString(index)
            self.GetParent().startTest(tel, path, testList)
            

DATABASE_NAME = "vehilce.db"
class VehicleListPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        
        self.info = db.VehicleInfo(db.Dbapi(DATABASE_NAME))
        self.layout()
        
    def layout(self):
        self.operation = wid.OperationPanel(self, '')
        items = [
                (ico.getBmp(u'car_new'), wx.ITEM_NORMAL, u'添加车辆', self.OnNewVehicle),
                (ico.getBmp(u'car_remove'), wx.ITEM_NORMAL, u'删除车辆', self.OnRemoveVehicle),
                (ico.getBmp(u'refresh'), wx.ITEM_NORMAL, u'刷新', self.OnRefresh),
                None,
                (ico.getBmp(u'play'), wx.ITEM_NORMAL, u'执行测试', self.OnPlay),
                (ico.getBmp(u'stop'), wx.ITEM_NORMAL, u'停止测试', self.OnStop),
                ]
        self.operation.layout(items)
        self.register = self._initVehicleRegister()
        self.register.Hide()
        self.removeit = self._initVehicleRemove()
        self.removeit.Hide()
        self.list = self._initVehicleList()

        self.mainsizer = wid.Sizer(wx.VERTICAL, flag = wx.EXPAND|wx.ALL, border = 1)
        self.mainsizer.Attach(self.operation, self.register, self.removeit)
        self.mainsizer.Add(self.list, proportion =1)
        self.SetSizer(self.mainsizer)
        self.Fit()
        self.refreshVehilce()
        
        
    def _newVehicle(self, tel):
        item = self.list.AppendItem(self.list.GetRootItem(), tel, ct_type = 1, 
                                    wnd = wid.TransBitmap(self.list))
        self.list.SetItemImage(item, self.CAR_OFF)
        self.GetParent().requestVehicleState(tel)
        return item
    
    def refreshVehilce(self):
        self.list.DeleteChildren(self.list.GetRootItem())
        for vehicle in self.info.readVehicle():
            self._newVehicle(vehicle[0])
        
    def updateVehicleState(self, tel, state):
        item = self.getItem(tel)
        if not item:return
        if state:
            self.list.SetItemImage(item, self.CAR_ON)
        else:
            self.list.SetItemImage(item, self.CAR_OFF)
            
    def updateVehicleTestState(self, tel, state):
        item = self.getItem(tel)
        if not item:return
        wnd = self.list.GetItemWindow(item)
        if state:
            wnd.SetBitmap(ico.getBmp(u'testing'))
        else:
            wnd.ClearBitmap()
            
    def updateAllState(self, state):
        if state:
            imgindex = self.CAR_ON
        else:
            imgindex = self.CAR_OFF
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            self.list.SetItemImage(item, imgindex)
            item = self.list.GetNextSibling(item)
        
    def getItem(self, tel):
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            if tel == self.list.GetItemText(item):
                return item
            item = self.list.GetNextSibling(item)
        
        
    def _initVehicleList(self):
        vlist = customtreectrl.CustomTreeCtrl(self, style = customtreectrl.TR_HIDE_ROOT
                                              |customtreectrl.TR_HAS_VARIABLE_ROW_HEIGHT
                                              |wx.BORDER_SIMPLE)
        vlist.AddRoot('root')
        vlist._imglist = wx.ImageList(16, 16)
        self.CAR_ON = vlist._imglist.Add(ico.getBmp(u'car_on'))
        self.CAR_OFF = vlist._imglist.Add(ico.getBmp(u'car_off'))
        vlist.SetImageList(vlist._imglist)
        return vlist
        
    def _initVehicleRegister(self):
        sizer = wid.Sizer(wx.HORIZONTAL, flag=wx.ALL, border = 3)
        text = wx.TextCtrl(self, style = wx.BORDER_SIMPLE, size = (100, 18))
        btnOK = wx.Button(self, style = wx.BORDER_NONE, label = u"注册", size = (40,20))
        btnCancel = wx.Button(self, style = wx.BORDER_NONE, label = u"取消", size = (40,20))
        sizer.Attach(text, btnOK, btnCancel)
        
        def Hide():
            text.Hide()
            btnOK.Hide()
            btnCancel.Hide()
        sizer.Hide = Hide
        
        def Show():
            text.SetValue("")
            text.SetFocus()
            for widget in [text, btnOK, btnCancel]:
                widget.Show()
        sizer.Show = Show
        
        def OnRegister(evt):
            tel = text.GetValue()
            if tel:
                self.registerVehicle(tel)
            sizer.Hide()
            self.mainsizer.Layout()
        
        def OnRegisterCancel(evt):
            sizer.Hide()
            self.mainsizer.Layout()
        self.Bind(wx.EVT_BUTTON, OnRegister, btnOK)
        self.Bind(wx.EVT_BUTTON, OnRegisterCancel, btnCancel)
        
        return sizer
    
    def _initVehicleRemove(self):
        sizer = wid.Sizer(wx.HORIZONTAL, flag=wx.ALL, border = 3)
        label = wx.StaticText(self, label = u"确定删除吗?", size = (100, 18))
        btnOK = wx.Button(self, style = wx.BORDER_NONE, label = u"确定", size = (40,20))
        btnCancel = wx.Button(self, style = wx.BORDER_NONE, label = u"取消", size = (40,20))
        sizer.Attach(label, btnOK, btnCancel)
        
        def Hide():
            label.Hide()
            btnOK.Hide()
            btnCancel.Hide()
        sizer.Hide = Hide
        
        def Show():
            label.Show()
            btnOK.Show()
            btnCancel.Show()
        sizer.Show = Show
        
        def OnDeleteSure(evt):
            self.removeVehicle()
            sizer.Hide()
            self.mainsizer.Layout()
        
        def OnDeleteCancel(evt):
            sizer.Hide()
            self.mainsizer.Layout()
        self.Bind(wx.EVT_BUTTON, OnDeleteSure, btnOK)
        self.Bind(wx.EVT_BUTTON, OnDeleteCancel, btnCancel)
        
        return sizer
    
    def OnNewVehicle(self, evt):
        self.register.Show()
        self.mainsizer.Layout()
        
    def OnRemoveVehicle(self, evt):
        self.removeit.Show()
        self.mainsizer.Layout()
        
    def OnRefresh(self, evt):
        self.refreshVehilce()

    def OnPlay(self, evt):
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            if self.list.IsItemChecked(item):
                testconfig_panel.addVehicle(self.list.GetItemText(item))
            item = self.list.GetNextSibling(item)
        
    def OnStop(self, evt):
        dlg = wid.AskingDialog(self, u"确定停止选中的测试?")
        result = dlg.ShowModal()
        dlg.Destroy()
        if result != wx.ID_OK:return
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            if self.list.IsItemChecked(item):
                self.GetParent().requestStopTest(self.list.GetItemText(item))
            item = self.list.GetNextSibling(item)
    
    def registerVehicle(self, tel):
        tel = tel.strip()
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item: 
            if self.list.GetItemText(item) == tel:
                return
            item = self.list.GetNextSibling(item)
        self.info.writeVehicle(tel)
        item = self._newVehicle(tel)
        
    def removeVehicle(self):
        _delete = []
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            if self.list.IsItemChecked(item):
                _delete.append(item)
            item = self.list.GetNextSibling(item)
        for item in _delete:
            tel = self.list.GetItemText(item)
            self.info.deleteVehicle(tel)
            self.list.Delete(item)

      
class TestFlowPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        
        self.operation = wid.OperationPanel(self, '')
        items = [
                (ico.getBmp('testflowimport'), wx.ITEM_NORMAL, u'导入测试', self.OnTestImport),
                None,
                (ico.getBmp('testflownew'), wx.ITEM_NORMAL, u'新建测试', self.OnTestNew),
                (ico.getBmp('testflowedit'), wx.ITEM_NORMAL, u'修改测试', self.OnTestEdit),
                (ico.getBmp('testflowremove'), wx.ITEM_NORMAL, u'移除测试', self.OnTestRemove),
                None,
                (ico.getBmp('refresh'), wx.ITEM_NORMAL, u'刷新', self.OnRefresh),
                None,
                (ico.getBmp('play'), wx.ITEM_NORMAL, u'执行测试', self.OnPlay),
                ]
        self.operation.layout(items)
        self.list = self._initTestList()
        
        mainsizer = wid.Sizer(wx.VERTICAL, flag=wx.EXPAND)
        mainsizer.Add(self.operation)
        mainsizer.Add(self.list, proportion =1)
        self.SetSizer(mainsizer)
        self.Fit()
        self.loadTests()
        
    def _initTestList(self):
        tlist = wx.TreeCtrl(self, style = wx.TR_HIDE_ROOT|wx.BORDER_SIMPLE|wx.NO_3D)
        tlist.AddRoot('root')
        #self.Bind(wx.EVT_TREE_ITEM_ACTIVATED , self.OnActivated)
        return tlist
    
    def loadTests(self):
        path = 'script/'
        def load(arg, dirname, filenames):
            for filename in filenames:
                if filename.endswith(".test"):
                    p = os.path.join(dirname, filename)
                    self.importTest(unicode(p, 'gbk'))
        os.path.walk(path, load, 0)

    def importTest(self, filename):
        if not filename: return
        item, cookie = self.list.GetFirstChild(self.list.GetRootItem())
        while item:
            if self.list.GetPyData(item) == filename:
                return
            item = self.list.GetNextSibling(item)
        name = os.path.basename(filename).rstrip('.test')
        item = self.list.AppendItem(self.list.GetRootItem(), name)
        self.list.SetPyData(item, filename)

    def OnTestImport(self, evt):
        dlg = wid.TestCaseOpenDialog(self)
        if dlg.ShowModal() == wx.ID_OK:
            paths = dlg.GetPaths()
            for path in paths:
                self.importTest(path)
        dlg.Destroy()
        
    def OnTestNew(self, evt):
        import testeditor
        testeditor.MainForm(self, size=(700, 400)).Show()
        
    def OnTestEdit(self, evt):
        import testeditor
        item = self.list.GetSelection()
        if item:
            f = testeditor.MainForm(self, size=(700, 400))
            f.importTest(self.list.GetPyData(item))
            f.Show()
    
    def OnTestRemove(self, evt):
        item = self.list.GetSelection()
        filename = self.list.GetPyData(item)
        if filename:
            dlg = wid.AskingDialog(self, u"确定要删除吗?")
            if dlg.ShowModal() == wx.ID_OK:
                try:
                    os.remove(filename.encode('gbk'))
                    self.list.Delete(item)
                except Exception, e:
                    dlgw = wid.WarningDialog(self, u"删除文件错误:\n%s"%e)
                    dlgw.ShowModal()
                    dlgw.Destroy()
            dlg.Destroy()
 
    def OnRefresh(self, evt):
        self.list.DeleteChildren(self.list.GetRootItem())
        self.loadTests()
            
    def OnPlay(self, evt):
        item = self.list.GetSelection()
        if item:
            testconfig_panel.addTest(self.list.GetItemText(item), 
                                      self.list.GetPyData(item))
   
class TrayIcon(wx.TaskBarIcon):
    def __init__(self, form):
        wx.TaskBarIcon.__init__(self)
        
        self.form = form
        self.SetIcon(form.GetIcon(), form.GetTitle())
        self.mnu = wx.Menu()
        self._createMenu("vehiclehunter", self.OnShowForm)
        self._createMenu("Exit", self.OnExit)
        
        self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnShowForm)
        self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, lambda evt:self.PopupMenu(self.mnu))
    
    def _createMenu(self, subname, event):
        _id = wx.NewId()
        self.mnu.Append(_id, subname)
        self.Bind(wx.EVT_MENU, event, id = _id)
        
    def OnShowForm(self, evt):
        if not self.form.IsShown():
            self.form.Show()
        if self.form.IsIconized():
            self.form.Restore()
        self.form.Raise()
        
    def OnExit(self, evt):
        self.form.Destroy()
        self.RemoveIcon()
        sys.exit()
        
        
def debug(msg):
    """debug interface"""
    if msg:exec(msg)
    
class DebugBox(wx.Panel):
    def __init__(self, *args, **kw):
        wx.Panel.__init__(self, *args, **kw)
        mainsizer = wid.Sizer(wx.HORIZONTAL, flag=wx.EXPAND)
        self.text = wx.TextCtrl(self, style = wx.TE_MULTILINE|wx.TE_AUTO_SCROLL|wx.TE_PROCESS_TAB)
        self.btn = wx.Button(self, label = u'Debug')
        mainsizer.Attach(self.text, proportion = 1)
        mainsizer.Attach(self.btn)
        self.SetSizer(mainsizer)
        self.Fit()
        self.Bind(wx.EVT_BUTTON, self.OnButton)
        
    def OnButton(self, evt):
        msg = self.text.GetValue()
        debug(msg)
        evt.Skip()
        
class StatusBar(wx.Window):
    def __init__(self, parent):
        wx.Window.__init__(self, parent, style=wx.BORDER_SUNKEN)
        
        
        self._lost = ico.getBmp('disconnected')
        self._connected = ico.getBmp('connected')
        
        self.label = wx.StaticText(self, label = u"")
        self.connectState = wx.StaticBitmap(self, bitmap=self._lost)
        
        mainsizer = wid.Sizer(wx.HORIZONTAL, flag=wx.EXPAND|wx.ALL, border=1)
        mainsizer.Add(self.connectState)
        mainsizer.Add(self.label, proportion=1)
        self.SetSizer(mainsizer)
        self.Fit()
        
    def showConnection(self, connected):
        if connected:
            self.connectState.SetBitmap(self._connected)
        else:
            self.connectState.SetBitmap(self._lost)
        self.Layout()
    
    def setLabel(self, label):
        self.label.SetLabel(label)
        
        
class InfoControlMixin:
    def testConnectState(self):
        connected = False
        if hasattr(self, 'ctrl'):
            connected = self.ctrl.isConnected()
        if not connected:
            state_panel.writeMessage(u"未连接到服务器,不能执行命令")
        return connected
        
    def startTest(self, tel, path, testFlowList):
        if self.testConnectState():
            state_panel.writeMessage(u"开始测试:%s"%tel)
            self.ctrl.setData(tel, testFlowList)
            self.ctrl.setPathName(tel, path)
            state_panel.appendVehicleState(tel)
            self.ctrl.requestStartTest(tel)
        
    def requestStopTest(self, tel):
        if self.testConnectState():
            self.ctrl.requestStopTest(tel)
        
    def requestVehicleState(self, tel):
        self.ctrl.requestVehicleState(tel)
            
    def requestTestProcess(self, tel):
        self.ctrl.requestTestProcess(tel)
    
    def setControl(self, control):
        self.ctrl = control

    
        
class MainForm(wx.Frame, InfoControlMixin):
    def __init__(self, ctrl):
        wx.Frame.__init__(self, None, title = "vehiclehunter")
        self.SetIcon(ico.getIcon("vehiclehunter"))
        self.setControl(ctrl)
        #tray = TrayIcon(self)
        self.mgr=aui.AuiManager()
        self.mgr.SetManagedWindow(self)
        
        global map_panel, testflow_panel, vehicle_panel, \
                state_panel, testconfig_panel, debug_panel, status_panel

        testflow_panel = TestFlowPanel(self) 
        self.mgr.AddPane(testflow_panel, aui.AuiPaneInfo().Name(u"testlist").
                                        Caption(u"测试用例").Left().FloatingSize((200,400)).
                                        Floatable(True).MinSize((220,-1)).
                                        CloseButton(True).MaximizeButton(False))
        
        vehicle_panel = VehicleListPanel(self)
        self.mgr.AddPane(vehicle_panel, aui.AuiPaneInfo().Name(u"vehiclelist").
                                        Caption(u"车辆列表").Left().FloatingSize((200,400)).
                                        Floatable(True).MinSize((220,-1)).
                                        CloseButton(True).MaximizeButton(False))
        '''
        map_panel = MapPanel(self)                             
        self.mgr.AddPane(map_panel, aui.AuiPaneInfo().Name(u"map").
                                        Caption(u"地图").Center().
                                        CloseButton(True).MaximizeButton(True))
        '''

        testconfig_panel = TestConfigPanel(self)
        self.mgr.AddPane(testconfig_panel, aui.AuiPaneInfo().Name(u"config").
                                        Caption(u"测试执行").Left().Position(1).
                                        CloseButton(True).MaximizeButton(False))
        
        state_panel = TestStatePanel(self)
        self.mgr.AddPane(state_panel, aui.AuiPaneInfo().Name(u"message").
                                        Caption(u"信息报告").Center().
                                        CloseButton(True).MaximizeButton(True))
        
        debug_panel = DebugBox(self)
        self.mgr.AddPane(debug_panel, aui.AuiPaneInfo().Name(u"debug").
                                        Caption(u"调试").Bottom().Hide().MinSize((-1, 100)).
                                        CloseButton(True))
        
        self.operation = wid.OperationPanel(self, '')
        items = [
                (ico.getBmp('paneltest'), wx.ITEM_NORMAL, u'测试列表', lambda evt:self.showPanel(testflow_panel)),
                (ico.getBmp('panelvehicle'), wx.ITEM_NORMAL, u'车辆列表', lambda evt:self.showPanel(vehicle_panel)),
                (ico.getBmp('panelstate'), wx.ITEM_NORMAL, u'状态报告', lambda evt:self.showPanel(state_panel)),
                (ico.getBmp('panelplay'), wx.ITEM_NORMAL, u'执行面板', lambda evt:self.showPanel(testconfig_panel)),
                None,
                (ico.getBmp('debug'), wx.ITEM_NORMAL, u'debug', lambda evt:self.showPanel(debug_panel)),
                None,
                (ico.getBmp('report'), wx.ITEM_NORMAL, u'查看报告', self.OnShowReport),
                ]
        self.operation.layout(items)
        self.mgr.AddPane(self.operation, aui.AuiPaneInfo().Name("operation").
                                        Caption("operation").Top().
                                        Floatable(True).MinSize((220,-1)).ToolbarPane().
                                        CloseButton(False).MaximizeButton(False))
        
        status_panel = StatusBar(self)
        self.mgr.AddPane(status_panel, aui.AuiPaneInfo().Name("statusbar").
                                        Caption(u"状态栏").Bottom().
                                        Floatable(False).ToolbarPane().MinSize((220,-1)).
                                        CloseButton(False).MaximizeButton(False))

        '''try:
            f = file(PERSPECTIVE_PATH, 'r')
            self.mgr.LoadPerspective(pickle.load(f))
        except:
            pass
        '''
        self.mgr.Update()
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        #self.Bind(aui.EVT_AUI_PANE_CLOSE, self.OnPaneClose)
        
    def showPanel(self, panel, show = True):
        if self.mgr.GetPane(panel).IsShown() != show:
            self.mgr.GetPane(panel).Show(show)
            self.mgr.Update()
            
    def OnShowReport(self, evt):
        reportform.ReportForm(self, size=(800,600)).Show()

    def OnClose(self, evt):
        map_panel = None
        testflow_panel = None
        vehicle_panel = None
        testconfig_panel = None
        state_panel = None
        debug_panel = None 
        status_panel = None
        self.Destroy()
            
map_panel = None
testflow_panel = None
vehicle_panel = None
testconfig_panel = None 
state_panel = None
debug_panel = None
status_panel = None     
              
if __name__ == '__main__':
    mainDir = os.path.dirname(os.getcwd())
    sys.path.append(mainDir)
    app = wx.App(0)
    app.MainLoop()
    
    